package com.wbc.demo;

import com.alibaba.fastjson.JSON;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;


/**
 * 可以在开发中开启，用于和前端联调时候查看前端的参数
 * @author wangbingchen
 * @Description
 * @create 2021-11-23 14:12
 * 调试打开看入参和返回结果 aop 测试利器
 * 输出所有注解了 RestController的类
 *
 */

@Aspect
@Component
public class WbcTestLogAOPDemo {


    @Resource
    private HttpServletRequest request;

//    // 定义切入注解
//    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
//    public void checkAccess(){
//    }

//     定义切入点 RestController 类上 注解切入
    @Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
    public void checkToken(){
    }


    //    // 定义切入点在方法上
//    @Pointcut("@annotation(com.linglong.report.annotion.Permission)")
//    public void checkToken(){
//    }

//    // 定义为类上 使用
//    @Pointcut("@within(com.linglong.bcard.annotion.Permission)")
//    public void checkToken(){
//    }


//    @Before("@within(org.springframework.web.bind.annotation.RestController)")
//    public void beforeMethod(JoinPoint joinPoint){
////        getParam(joinPoint, reObj);
////        String methodName = joinPoint.getSignature().getName();
////        List<Object> args = Arrays.asList(joinPoint.getArgs());
////        System.out.println("beforeMethod "+methodName+" and "+args);
//    }



    /**
     * 处理未处理的JAVA异常
     * @author:SimpleWu
     * @Date:2018年10月12日
     */
    @AfterThrowing(pointcut="checkToken()",throwing="e")
    public void exception(JoinPoint joinPoint, Exception e){
        System.out.println("异常切入:"+e.getMessage());

    }

    /**
     * 定义一个最终通知
     * @author:SimpleWu
     * @Date:2018年10月12日
     */
    @AfterReturning(pointcut="checkToken()", returning="reObj")
    public void aopAfterReturning(JoinPoint joinPoint, Object reObj) {
        synchronized (WbcTestLogAOPDemo.class){
            getParam(joinPoint,reObj);
        }
    }




    /**
     * 环绕通知
     * @author:SimpleWu
     * @throws Throwable
     * @Date:2018年10月12日
     */
    @Around("checkToken()")
    public Object around(ProceedingJoinPoint invocation) throws Throwable{
//        getParam(invocation, reObj);
        Object proceed;
        try {
            //这个就是切入点的方法
            proceed =invocation.proceed();
        }catch (Exception e){
            e.printStackTrace();
            throw e;
        }

        return proceed;
    }


    /**
     *  打印前端传过来的参数
     * @return 字符串
     * @param joinPoint
     * @param reObj
     */
    public void getParam(JoinPoint joinPoint, Object reObj) {
        SimpleDateFormat yyyyMMddHHmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = yyyyMMddHHmmss.format(new Date());
        System.out.println("**************************** 开始 "+format+" ****************************");
        //form-data
        String contextPath = request.getServletPath();
        System.out.println("接口名称："+contextPath+"\n");
        Enumeration enu=request.getParameterNames();
        System.out.println("form-data请求参数：");
        while(enu.hasMoreElements()){

            String paraName=(String)enu.nextElement();
            System.out.println(paraName+": "+request.getParameter(paraName));
        }


        //json
        BufferedReader reader = null;

        try{
            reader = request.getReader();
        }catch (Exception e){
        }

        StringBuilder contentBuilder= new StringBuilder();
        if(reader!=null){
            char[] buf = new char[512];
            int len;
            while (true) {
                try {
                    if ((len = reader.read(buf)) == -1) break;
                } catch (IOException e) {
                    e.printStackTrace();
                    break;
                }
                contentBuilder.append(buf, 0, len);
            }

        }else {
            Object[] args = joinPoint.getArgs();
            if(args.length>0){
                contentBuilder.append(args[0]);
            }
        }

        System.out.println("\njson 请求参数：");
        System.out.println(contentBuilder.toString());

        System.out.println("这个是切入方法的返回:"+ JSON.toJSONString(reObj));
        System.out.println("**************************** 结束 "+format+" ****************************");


    }


}
